package org.red5.core;

import java.util.ArrayList;
 
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IClient;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.Red5;
import org.red5.server.api.service.IServiceCapableConnection;
import org.red5.server.api.so.ISharedObject;
import org.red5.server.api.stream.IStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

 
public class Application extends ApplicationAdapter {
	
 
	@Override
	public boolean appStart(IScope scope) {
		registerStreamPublishSecurity(new AuthNamePublishSecurity());
		//registerSharedObjectSecurity(new SOSecurityHandler());
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.appStart - WikiChat #############################" );
		System.out.println( "##############################################################################" );
		return true;
	}
 
	@Override
	public synchronized boolean roomStart(IScope room) {
		if( !super.roomStart(room) ) return false;
		createSharedObject(room, "roomSO", false);
 
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.roomStart ############################" );
		System.out.println( "##############################################################################" );
		return true;
	}
 
	@Override
	public synchronized boolean appConnect(IConnection conn, Object[] params) {
		if (params == null || params.length == 0) {
			rejectClient("No username passed.");
		}
 
		IClient client = conn.getClient();
		String userName = params[0].toString();

		
		client.setAttribute( "userName", userName );
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.appConnect - WikiChat ###########################" );
		System.out.println( "##############################################################################" );
		return true;
	}
 
	@Override
	public synchronized boolean roomConnect(IConnection conn, Object[] params) {
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.roomConnect - WikiChat ##########################" );
		System.out.println( "##############################################################################" );
		return true;
	}
 
	@Override
	public synchronized boolean appJoin(IClient client, IScope scope) {
		IConnection conn = Red5.getConnectionLocal();
		IServiceCapableConnection service = (IServiceCapableConnection) conn;
		Object[] param = new Object[] { client.getId() };
		//service.invoke("setID", param);
 
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.appJoin - WikiChat ##############################" );
		System.out.println( "##############################################################################" );
		return super.appJoin(client, scope);
	}
	@Override
	public synchronized boolean roomJoin(IClient client, IScope room) {
		if( super.roomJoin(client, room) ) {
			ISharedObject so = getSharedObject(room, "roomSO");
			ArrayList<String> oldUserList = new ArrayList<String> ();
			ArrayList<String> newUserList = new ArrayList<String> ();
			String userName = (String) client.getAttribute("userName");
			
			
			if (oldUserList.contains(userName)){
				rejectClient("already connected");
			}
			
			ArrayList<String> temp = new ArrayList<String>();
			temp.add(userName);
			
			Object[] obj = (Object[]) so.getAttribute("userList");
			if( obj != null ) {
				for(int i=0; i<obj.length; i++) {
					oldUserList.add( (String) obj[i] );
				}
				newUserList.addAll( oldUserList );
			}
			newUserList.add( (String) client.getAttribute("userName") );
			so.setAttribute("userList", newUserList.toArray());
			System.out.println("so.getAttribute(userList): "+so.getAttribute("userList").toString());
			
			System.out.println("newUserList: "+newUserList);
			so.sendMessage("addUser", temp);
		}
		System.out.println( "###########################################################################################" );
		System.out.println( "############################ Red5Demo.roomJoin - WikiChat #############################" );
		System.out.println( "###########################################################################################" );
		System.out.println();
		return true;
	}
	
	@Override
	public synchronized void roomLeave(IClient client, IScope room) {
		ISharedObject so = getSharedObject(room, "roomSO");
		ArrayList<String> oldUserList = new ArrayList<String> ();
		ArrayList<String> newUserList = new ArrayList<String> ();
		ArrayList<String> temp = new ArrayList<String>();
		
		String userName = (String) client.getAttribute("userName");
		temp.add(userName);
		
		
		Object[] obj = (Object[]) so.getAttribute("userList");
		if( obj != null ) {
			for(int i=0; i<obj.length; i++) {
				oldUserList.add( (String) obj[i] );
			}
			newUserList.addAll( oldUserList );
		}
		newUserList.remove( userName );
		
		if (so != null){
			so.setAttribute("userList", newUserList.toArray());
			System.out.println("userListChange: "+ newUserList);
			so.sendMessage("userListRemove", temp);
			System.out.println("nachuserlist: "+so);
		}
		
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.roomLeave - WikiChat ############################" );
		System.out.println( "##############################################################################" );
	}
 
	@Override
	public void roomStop(IScope room) {
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.roomStop - WikiChat #############################" );
		System.out.println( "##############################################################################" );
		super.roomStop(room);
	}
 
	@Override
	public void disconnect(IConnection conn, IScope scope) {
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.disconnect - WikiChat ###########################" );
		System.out.println( "##############################################################################" );
		super.disconnect(conn, scope);
 
	}
 
	@Override
	public void appStop( IScope scope ) {
		log.debug(" Red5Demo.appStop - WikiChat/ "+scope.getName());
		System.out.println( "##############################################################################" );
		System.out.println( "############################ Red5Demo.appStop - WikiChat #############################" );
		System.out.println( "##############################################################################" );
	}
	
	public synchronized ArrayList<String> getUserList(){
		ArrayList<String> userList = new ArrayList<String> ();

    	IScope room = Red5.getConnectionLocal().getScope();
    	ISharedObject so = getSharedObject(room, "roomSO");
    	
    	Object[] obj = (Object[]) so.getAttribute("userList");
		if( obj != null ) {
			for(int i=0; i<obj.length; i++) {
				userList.add( (String) obj[i] );
			}
		}
			
    	System.out.println("getShapeList scope: "+room+" userList: "+userList);
    	return userList;
	}
	
	
 
}

